local MB = {}

if string.find(string.lower(GAMEMODE.Name),"terror") then MB.TTT = true else MB.TTT = false end
if string.find(string.lower(GAMEMODE.Name),"darkrp") then MB.DRP = true else MB.DRP = false end

MB.lp = LocalPlayer

MB.hooks = {}
MB.hookdesc = {}
MB.commands = {}
MB.commanddesc = {}
MB.timers = {}
MB.timerdesc = {}
MB.aim = false
MB.aimalways = false
MB.meep = true
MB.meepbot = false
MB.targ = nil

MB.allwep = {}
MB.traitorz = {}
MB.witnesses = {}
MB.deadpplz = {}
MB.mat = CreateMaterial(math.random(1337,13370), "VertexLitGeneric", { ["$basetexture"] = "models/debug/debugwhite", ["$model"] = 1, ["$ignorez"] = 1 } )
MB.donottrack = {"viewmodel", "weapon_ttt_wtester", "weapon_zm_improvised", "weapon_zm_magnetstick", "weapon_zm_carry", "weapon_ttt_unarmed", "env_fire", "ttt_flame", "ttt_knife_proj", "prop_ragdoll", "trace1", "rope", "func_physbox", "ttt_firegrenade_proj", "ttt_smokegrenade_proj", "ttt_confgrenade_proj"}
for k, v in pairs(ents.GetAll()) do
    v.isPartOfMap = true
    if not table.HasValue(MB.allwep,v:GetClass()) and v:IsWeapon() and not table.HasValue(MB.donottrack,v:GetClass()) then
        table.insert(MB.allwep,v:GetClass())
    end
end

function MB.dist(v1,v2)
    return v1:Distance(v2)
end

function MB.CSP(E2)
    if IsValid(LocalPlayer()) and IsValid(E2) and LocalPlayer() and E2 then
        local aaa = {}
        aaa.start = EyePos()
        aaa.endpos = E2:Pos()
        aaa.filter = LocalPlayer()
        local traceRes = util.TraceLine(aaa)
        if traceRes.HitNonWorld and traceRes.Entity == E2 then
            return true
        else 
            return false
        end
    end
end

/*
function MB.GetPeopleWhoCanSee(targ)
    local ppl = {}
    local fov = MB.lp():GetFOV()
    if targ and IsValid(targ) then
        chat.AddText("1")
        for _,ply in pairs (player.GetAll()) do
            if ply and IsValid(ply) then
                chat.AddText("2")
                local tracedata = {}
                local aa, ab= ply:GetBonePosition(ply:LookupBone("ValveBiped.Bip01_Head1"))
	
                tracedata.start = MB.lp():EyePos()
                tracedata.endpos = aa
                tracedata.filter = MB.lp()
                local trace = util.TraceLine(tracedata)
                local gav = ply:GetAimVector():
                local baa = trace.HitPos.x / trace.StartPos.x
                local bab = trace.HitPos.y / trace.StartPos.y
                local bac = trace.HitPos.z / trace.StartPos.z
                local ba = Vector(baa,bab,bac)
                chat.AddText("Normal: "..tostring(ba))
                chat.AddText("x: "..tostring(baa))
                chat.AddText("y: "..tostring(bab))
                chat.AddText("z: "..tostring(bac))
                chat.AddText("gav: "..tostring(gav))
                if not trace.HitWorld and trace.Entity == targ then
                        //table.insert(ppl,ply)
                    
                end
            end
        end
    end
    return ppl
end
*/

function MB.CreateTimer(timerdesc,timername,timeamt,times,functiontimer)
    timer.Create(timername,timeamt,times,functiontimer)
    MB.timers[timerdesc] = timername
    MB.timerdesc[timername] = timerdesc
end

function MB.AddHook(Type,Function)
    Name = Type.." | "..math.random(1,1297),math.random(1,2282),math.random(1,7236)
    MB.hooks[Name] = Type
    MB.hookdesc[Type] = Name
    hook.Add(Type,Name,Function)
    return Name
end

function MB.AddCommand(Number,NumberNode,Function)
    MB.commands[NumberNode] = Number
    MB.commanddesc[Number] = NumberNode
    concommand.Add(Number,Function)
end

MB.AddCommand(math.random(100000,10000000),"Wallhack.Toggle",function()
    MB.meep = !MB.meep
end)

MB.AddCommand(tostring(math.random(1,10000)),"TTT Enable",function()
    MB.TTT = !MB.TTT
end)

MB.AddCommand("meepbot","WikiAimbot.ToggleUntilDead",function()
    MB.aim = not MB.aim
    
end)

function MB.MESPCheck(v)
    if MB.TTT then
        if IsValid(v) and v:IsPlayer() and not v:IsNPC() and v:IsTerror() ~= nil and v:IsTerror() and not table.HasValue(MB.deadpplz,v) and v ~= MB.lp() then
            return true
        else
            return false
        end
    else
        if IsValid(v) and v:IsPlayer() and not v:IsNPC() and not table.HasValue(MB.deadpplz,v) and v ~= MB.lp() then
            return true
        else
            return false
        end
    end
end

function MB.coordinates(ent)
local min, max = ent:OBBMins(), ent:OBBMaxs()
local corners = {
    Vector(min.x, min.y, min.z),
    Vector(min.x, min.y, max.z),
    Vector(min.x, max.y, min.z),
    Vector(min.x, max.y, max.z),
    Vector(max.x, min.y, min.z),
    Vector(max.x, min.y, max.z),
    Vector(max.x, max.y, min.z),
    Vector(max.x, max.y, max.z)
}
 
local minX, minY, maxX, maxY = ScrW() * 2, ScrH() * 2, 0, 0
for _, corner in pairs(corners) do    
    local onScreen = ent:LocalToWorld(corner):ToScreen()
    minX, minY = math.min(minX, onScreen.x), math.min(minY, onScreen.y)
    maxX, maxY = math.max(maxX, onScreen.x), math.max(maxY, onScreen.y)
end
 
return minX, minY, maxX, maxY
end

local function meepbot()
    local lp = MB.lp()
    local trace = util.GetPlayerTrace(lp)
    local traceRes = util.TraceLine(trace)
    if traceRes.HitNonWorld then
        local target = traceRes.Entity
        if target:Health() > 0 and IsValid(target) and v ~= lp then
            MB.temptarg = target
        end
    end
    if MB.aim and IsValid(MB.targ) and MB.targ:Health() > 0 then
        local targethead = MB.targ:LookupBone("ValveBiped.Bip01_Head1")
        if targethead then
            local targetheadpos,targetheadang = MB.targ:GetBonePosition(targethead)
            if targetheadpos and targetheadang then
                lp:SetEyeAngles((targetheadpos - lp:GetShootPos()):Angle())
            end
        end
    else
        MB.aim = false
        MB.targ = MB.temptarg
    end
end

MB.AddHook("Think",meepbot)

local function drawnames() 
    if MB.meep then
        cam.Start2D()
        for k,v in pairs (player.GetAll()) do
            if MB.MESPCheck(v) then
            --Name Draw start
                local Position = v:GetPos():ToScreen()
                local name = v:Name()
                if MB.TTT then
                    if not table.HasValue(MB.traitorz,v) then
                        if v:IsDetective() then 
                            draw.DrawText(name.."\n Detective", "BudgetLabel", Position.x, Position.y, Color(0, 0, 255, 250), 1)
                        else
                            draw.DrawText(name.."\n Innocent", "BudgetLabel", Position.x, Position.y, Color(0, 255, 0, 250), 1)
                        end
                    else
                        if v:IsDetective() then 
                            draw.DrawText(name.."\n Detective", "BudgetLabel", Position.x, Position.y, Color(0, 0, 255, 250), 1)
                        else
                            draw.DrawText(name.."\n Traitor", "BudgetLabel", Position.x, Position.y, Color(255, 0, 0, 250), 1)
                        end
                    end
                elseif MB.DRP then
                    draw.DrawText(name.."\n Health: "..tostring(v:Health()), "BudgetLabel", Position.x, Position.y, team.GetColor(v:Team()), 1)
                else
                    draw.DrawText(name.."\n Health: "..tostring(v:Health()), "BudgetLabel", Position.x, Position.y, Color(102, 102, 255, 250 ), 1)
                end
            --Name Draw finish
            end
        end
        cam.End2D()
    end
end

MB.CreateTimer("Dead people checker",tostring(math.random(100,1000000)), 1, 0, function()
	for _,v in pairs (player.GetAll()) do
        if not v:Alive() and v:Health() < 1 and not v:IsNPC() and v:IsPlayer() then
            if not table.HasValue(MB.deadpplz,v) then
                table.insert(MB.deadpplz,v)
                chat.AddText(v:Name().." died somehow!")
            end
        else
            for k,v2 in pairs (MB.deadpplz) do
                if v2 == v then
                    table.remove(MB.deadpplz,k)
                end
            end
        end
    end
end)

local function rp()
    if MB.meep then
        local lp = MB.lp()
        cam.Start3D(lp:EyePos(), lp:EyeAngles())
        
        render.SuppressEngineLighting(true)
        render.MaterialOverride(MB.mat)
        for k,v in pairs(player.GetAll()) do
            if MB.MESPCheck(v) then
            --draw people start
                --part 1
                local h = v:Health()
                local green = (2.55 * h) / 255
                local red = (255 - 2.00 * h) / 255
                render.SetColorModulation(red, green, 0, 1)
                render.MaterialOverride(MB.mat)
                v:DrawModel()
                
                --part 2
                render.MaterialOverride()
                render.SetModelLighting(4, 0.78, 0.19, 0.19)
                v:DrawModel()
            --draw people finish
            
            --draw guns start
                if IsValid(v:GetActiveWeapon()) then
                    render.SetColorModulation(0, 0, 0, 1)
                    render.MaterialOverride(MB.mat)
                    v:GetActiveWeapon():DrawModel()
                    
                    render.SetColorModulation(0, 0, 0, 1)
                    render.MaterialOverride()
                    v:GetActiveWeapon():DrawModel() 
                end
            --draw guns finish
            end
        end
        render.SuppressEngineLighting(false)
        cam.End3D()
    end
end

MB.AddHook("RenderScreenspaceEffects",rp)

if MB.TTT then
    MB.AddHook("TTTPrepareRound",function()
        traitorfinder = false
        for k, v in pairs(MB.allwep) do
            table.remove(MB.allwep, k)
            MB.allwep = {}
        end
        MB.targ = nil
        MB.temptarg = nil
        for _,v in pairs(ents.GetAll()) do
            v.isPartOfMap = true
        end
    end)

    MB.AddHook("TTTBeginRound",function()
        traitorfinder = true
        for k, v in pairs(ents.GetAll()) do
            v.isPartOfMap = true
            if not table.HasValue(MB.allwep,v:GetClass()) and v:IsWeapon() and not table.HasValue(MB.donottrack,v:GetClass()) then
                table.insert(MB.allwep,v:GetClass())
            end
        end
        MB.traitorz = {}
        MB.deadpplz = {}
    end)
end

MB.AddHook("HUDPaint", drawnames)

MB.AddHook("PostDrawOpaqueRenderables", function()
    if MB.TTT then
        for k, v in pairs(ents.GetAll()) do
            if v and MB.meep and traitorfinder and IsValid(v) then
                if not table.HasValue(MB.allwep,v:GetClass()) and v.CanBuy and not v.isPartOfMap and not v.wasESPTracked and not table.HasValue(MB.donottrack,v:GetClass()) then
                    pl = v.Owner
                    if MB.MESPCheck(pl) and IsValid(pl) and pl then
                        v.wasESPTracked = true
                        table.insert(MB.traitorz,pl)
                        chat.AddText(pl, Color(255,125,0), " is a ",Color(255,0,0), "TRAITOR",Color(255,125,0), " with a ",Color(255,0,0),tostring(v:GetPrintName()).."!")
                    end
                end
            end
        end
    end
end)

MB.AddCommand(math.random(1000,100000),"ShowWindow",function()
    local rows = 2
    local columns = 3
    local extrah = 27
    local extraw = 3
    local totalwidth = 3 + 103 * (columns * 3)
    local totalheight = 27 * (rows + 1)
    
    local Frame = vgui.Create("DFrame")
    Frame:SetSize(209,totalheight)
    Frame:SetPos(25,25)
    Frame:SetText("MeepBot settings")
    Frame:MakePopup()
    
    local vguiaimbotb = vgui.Create("DButton",Frame)
    if MB.aimalways or MB.aim then vguiaimbotb:SetText("Aimbotv1 on") else vguiaimbotb:SetText("Aimbotv1 off") end
    vguiaimbotb:SetPos(extraw,extrah)
    vguiaimbotb:SetWide(100)
    function vguiaimbotb:DoClick()
        MB.aimalways = !MB.aimalways
        if MB.aimalways or MB.aim then self:SetText("Aimbotv1 on") else self:SetText("Aimbotv1 off") end
    end
    
    local vguimaintoggleb = vgui.Create("DButton",Frame)
    if MB.meep then vguimaintoggleb:SetText("Wallhack on") else vguimaintoggleb:SetText("Wallhack off") end
    vguimaintoggleb:SetPos(extraw,extrah * 2)
    vguimaintoggleb:SetWide(100)
    function vguimaintoggleb:DoClick()
        MB.meep = !MB.meep
        if MB.meep then self:SetText("Wallhack on") else self:SetText("Wallhack off") end
    end
    
    local vguibindb = vgui.Create("DButton",Frame)
    vguibindb:SetPos(extraw * 2 + 100,extrah * 2)
    vguibindb:SetWide(100)
    vguibindb:SetText("List binds in ~")
    function vguibindb:DoClick()
        for _,v in pairs(MB.commands) do
            MsgN("\n"..v.." is "..MB.commanddesc[v])
        end
    end
    
    local vguitttb = vgui.Create("DButton",Frame)
    vguitttb:SetPos(extraw * 1,extrah * 3)
    vguitttb:SetWide(100)
    if MB.TTT then
        vguitttb:SetText("TTT Enabled")
    else
        vguitttb:SetText("TTT Disabled")
    end
    function vguitttb:DoClick()
        MB.TTT = !MB.TTT
        if MB.TTT then
            vguitttb:SetText("TTT Enabled")
        else
            vguitttb:SetText("TTT Disabled")
        end
    end
    
    local vguiselfdestructb = vgui.Create("DButton",Frame)
    vguiselfdestructb:SetPos(extraw * 2 + 100,extrah)
    vguiselfdestructb:SetWide(100)
    vguiselfdestructb:SetText("Self Destruct")
    function vguiselfdestructb:DoClick()
        for _,v in pairs(MB.hooks) do
            hook.Remove(v,MB.hookdesc[v])
        end
        for _,v in pairs (MB.timers) do
            timer.Remove(v)
        end
        for _,v in pairs (MB.commands) do
            concommand.Remove(v)
        end
        Frame:SetVisible(false)
    end
    
end)

chat.AddText("Bind a key to: "..MB.commands["ShowWindow"])
